package Q16_09_Operations;
import java.util.Random;
import CtCILibrary.AssortedMethods;
public class Question {
/* Flip a positive sign to negative, or a negative sign to pos */
public static int negate(int a) {
int neg = 0;
int newSign = a < 0 ? 1 : -1;
while (a != 0) {
neg += newSign;
a += newSign;
}
return neg;
}
/* Flip a positive sign to negative, or a negative sign to pos */
public static int negateOptimized(int a) {
int neg = 0;
int newSign = a < 0 ? 1 : -1;
int delta = newSign;
while (a != 0) {
boolean differentSigns = (a + delta > 0) != (a > 0);
if (a + delta != 0 && differentSigns) { // If delta is too big, reset it.
delta = newSign;
}
neg += delta;
a += delta;
delta += delta; // Double the delta
}
return neg;
}
/* Subtract two numbers by negating b and adding them */
public static int minus(int a, int b) {
return a + negate(b);
}
/* Return absolute value */
public static int abs(int a) {
if (a < 0) {
return negateOptimized(a);
}
else return a;
}
/* Multiply a by b by adding a to itself b times */
public static int multiply(int a, int b) {
if (a < b) {
return multiply(b, a); // algo is faster if b < a
}
int sum = 0;
for (int i = abs(b); i > 0; i = minus(i, 1)) {
sum += a;
}
if (b < 0) {
sum = negateOptimized(sum);
}
return sum;
}
/* Divide a by b by literally counting how many times b can go into
* a. That is, count how many times you can add b to itself until you reach a. */
public static int divide(int a, int b) throws java.lang.ArithmeticException {
if (b == 0) {
throw new java.lang.ArithmeticException("ERROR: Divide by zero.");
}
int absa = abs(a);
int absb = abs(b);
int product = 0;
int x = 0;
while (product + absb <= absa) { /* don't go past a */
product += absb;
x++;
}
if ((a < 0 && b < 0) || (a > 0 && b > 0)) {
return x;
} else {
return negateOptimized(x);
}
}
public static void main(String[] args) {
int minRange = -100;
int maxRange = 100;
int cycles = 100;
for (int i = 0; i < cycles; i++) {
int a = AssortedMethods.randomIntInRange(minRange, maxRange);
int b = AssortedMethods.randomIntInRange(minRange, maxRange);
int ans = minus(a, b);
if (ans != a - b) {
System.out.println("ERROR");
}
System.out.println(a + " - " + b + " = " + ans);
}
for (int i = 0; i < cycles; i++) {
int a = AssortedMethods.randomIntInRange(minRange, maxRange);
int b = AssortedMethods.randomIntInRange(minRange, maxRange);
int ans = multiply(a, b);
if (ans != a * b) {
System.out.println("ERROR");
}
System.out.println(a + " * " + b + " = " + ans);
}
for (int i = 0; i < cycles; i++) {
int a = AssortedMethods.randomIntInRange(minRange, maxRange);
int b = AssortedMethods.randomIntInRange(minRange, maxRange);
System.out.print(a + " / " + b + " = ");
int ans = divide(a, b);
if (ans != a / b) {
System.out.println("ERROR");
}
System.out.println(ans);
}
}
}